# 动态生成用例
from pathlib import Path

import allure
import pytest
import logging

from commons.exchange import Exchange
from commons.files import YamlFile
from commons.models import CaseInfo
from commons.session import Session

session = Session("http://172.31.115.4:35510/dev-api/")
logger = logging.getLogger(__name__)

# yaml用例存放目录
_case_path = Path(r"D:\python\TestClass\ssy_api_auto_test\testcases")
exchanger = Exchange(r"D:\python\TestClass\ssy_api_auto_test\extract.yaml")


# @allure.epic("项目名称：接口自动化测试")
class TestAPI:  # 可以被pytest框架识别的测试类
    ...

    @classmethod  # 类方法
    def find_yaml_case(cls, case_path: Path = _case_path):
        """
        寻找和加载yaml文件
        :return:
        """
        yaml_path_list = case_path.glob("**/test_*.yaml")
        for yaml_path in yaml_path_list:
            logger.info(f"load file {yaml_path=}")

            file = YamlFile(yaml_path)  # 自动读取yaml文件
            case_info = CaseInfo(**file)  # 自动验证yaml格式

            logger.debug(case_info.to_yaml())  # 把case_info转成字符串，然后记录日志

            case_func = cls.new_case(case_info)  # 从yaml格式转为pytest格式
            setattr(cls, f"{yaml_path.name}", case_func)  # 用例添加到类中

    @classmethod  # 类方法
    def new_case(cls, case_info: CaseInfo):

        ddt_data = case_info.ddt()
        ddt_title = [data.title for data in ddt_data]

        @allure.epic(case_info.epic)
        @allure.feature(case_info.feature)
        @allure.story(case_info.story)
        @pytest.mark.parametrize("case_info", ddt_data, ids=ddt_title)
        def test_func(self, case_info: CaseInfo):
            allure.dynamic.title(case_info.title)

            logger.info(f"用例开始执行：{case_info.title}".center(80, "="))

            # 0.变量替换
            new_case_info = exchanger.replace(case_info)
            logger.info("1.正在注入变量...")
            logger.debug(f"{exchanger.file}")
            # 1.发送请求
            logger.info("2.正在请求接口...")
            resp = session.request(**new_case_info.request)

            logger.info("3.正在提取变量...")
            # 2.保存变量（接口关联）
            if new_case_info.extract:
                for var_name, extract_info in new_case_info.extract.items():
                    # exchanger.extract(resp, var_name, extract_info[0], extract_info[1], extract_info[2])
                    exchanger.extract(resp, var_name, *extract_info)
            else:
                pass
            # 3.断言
            logger.info("4.正在断言...")
            assert_case_info = exchanger.replace(case_info)  # 为断言加载变量
            assert_case_info.assert_all()  # 执行断言

            logger.info(f"用例执行结束：{case_info.title}".center(80, "="))

        return test_func


# TestAPI.find_yaml_case(Path(r"testcases"))  # 加载yaml文件
